package main

import (
	"fmt"
	"sync"
	"time"
)

/*
读写锁
1、读共享- 多线程读取时，不用上锁子，同时可以读取
2、写上锁- 有写的进程，写数据之前一定会上锁
3、写优先- 如果不优先，一直有读取的进程，就无法更新， 优先可以保证数据的实时性
*/

var (
	wg      sync.WaitGroup //等待 协程处理
	rwMutex sync.RWMutex   //读写锁子
	data    int            //原始数据 共享数据
)

func main() {
	for i := 0; i < 7; i++ {
		wg.Add(1)
		go reader(i)
	}
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go writer(i)
	}
	wg.Wait()
}

func reader(num int) {
	for {
		rwMutex.RLock()
		fmt.Printf("read num=%d,data=%d \n", num, data)
		time.Sleep(time.Millisecond * 5)
		rwMutex.RUnlock()
	}
	wg.Done() //死代码 wg 永远不done  所有会一直循环输出

}

func writer(num int) {
	for {
		rwMutex.Lock()
		data++
		fmt.Printf("write num=%d,data=%d \n", num, data)
		time.Sleep(time.Millisecond * 5)
		rwMutex.Unlock()
	}
	wg.Done()
}
